package com.fjec.market.service.impl;

import com.fjec.market.mapper.*;
import com.fjec.market.service.IStatService;
import com.fjec.common.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.*;

@Slf4j
@Service
public class StatServiceImpl implements IStatService {

    @Resource
    private InfoFarmerMapper farmerMapper;

    @Resource
    private InfoBusinessMapper businessMapper;

    @Resource
    private InfoPurchaseMapper purchaseMapper;

    @Resource
    private InfoPersonalMapper personalMapper;

    @Resource
    private BizSubPhysicalOrderMapper subPhysicalOrderMapper;

    @Resource
    private InfoMarketMapper marketMapper;

    @Override
    public List<Map<String, Object>> statFarmerData(int days) {
        List<Map<String, Object>> resultMapList = new ArrayList<>();
        // 获取所有市场
        List<Map<String, Object>> marketList = marketMapper.getAllMarketCode();
        // 计算需要统计的日期列表
        List<LocalDateTime> dateList = this.computeStatDateList(days);
        // 处理所有日期
        for (LocalDateTime statDate : dateList) {
            LocalDateTime startTime = LocalDateTime.of(statDate.toLocalDate(), LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(statDate.toLocalDate(), LocalTime.MAX);
            List<Map<String, Object>> farmerMapList = farmerMapper.statFarmerData(startTime, endTime);
            for (Map<String, Object> market : marketList) {
                int marketCode = MapUtils.getIntValue(market, "MarkCode");
                Map<String, Object> tmpMap = null;
                for (Map<String, Object> farmerMap : farmerMapList) {
                    int farmerMarketCode = MapUtils.getIntValue(farmerMap, "MarkCode");
                    if (marketCode == farmerMarketCode) {
                        tmpMap = farmerMap;
                    }
                }
                if (tmpMap == null) {
                    tmpMap = new HashMap<>();
                    tmpMap.put("MarkCode", marketCode);
                    tmpMap.put("Num", 0);
                    tmpMap.put("StatDate", DateUtil.format(statDate, "yyyy-MM-dd"));
                }
                resultMapList.add(tmpMap);
            }
        }
        return resultMapList;
    }

    @Override
    public List<Map<String, Object>> statBusinessData(int days, int busiType) {
        List<Map<String, Object>> resultMapList = new ArrayList<>();
        // 获取所有市场
        List<Map<String, Object>> marketList = marketMapper.getAllMarketCode();
        // 计算需要统计的日期列表
        List<LocalDateTime> dateList = this.computeStatDateList(days);
        // 处理所有日期
        for (LocalDateTime statDate : dateList) {
            LocalDateTime startTime = LocalDateTime.of(statDate.toLocalDate(), LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(statDate.toLocalDate(), LocalTime.MAX);
            List<Map<String, Object>> businessMapList = businessMapper.statBusinessData(startTime, endTime, busiType);
            for (Map<String, Object> market : marketList) {
                int marketCode = MapUtils.getIntValue(market, "MarkCode");
                Map<String, Object> tmpMap = null;
                for (Map<String, Object> businessMap : businessMapList) {
                    int businessMarketCode = MapUtils.getIntValue(businessMap, "MarkCode");
                    if (marketCode == businessMarketCode) {
                        tmpMap = businessMap;
                    }
                }
                if (tmpMap == null) {
                    tmpMap = new HashMap<>();
                    tmpMap.put("MarkCode", marketCode);
                    tmpMap.put("Num", 0);
                    tmpMap.put("StatDate", DateUtil.format(statDate, "yyyy-MM-dd"));
                }
                resultMapList.add(tmpMap);
            }
        }
        return resultMapList;
    }

    @Override
    public List<Map<String, Object>> statPurchaseData(int days) {
        List<Map<String, Object>> resultMapList = new ArrayList<>();
        // 计算需要统计的日期列表
        List<LocalDateTime> dateList = this.computeStatDateList(days);
        // 处理所有日期
        for (LocalDateTime statDate : dateList) {
            LocalDateTime startTime = LocalDateTime.of(statDate.toLocalDate(), LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(statDate.toLocalDate(), LocalTime.MAX);
            List<Map<String, Object>> purchaseMapList = purchaseMapper.statPurchaseData(startTime, endTime);
            if (purchaseMapList != null && !purchaseMapList.isEmpty()) {
                resultMapList.addAll(purchaseMapList);
            } else {
                Map<String, Object> tmpMap = new HashMap<>();
                tmpMap.put("Num", 0);
                tmpMap.put("StatDate", DateUtil.format(statDate, "yyyy-MM-dd"));
                resultMapList.add(tmpMap);
            }
        }
        return resultMapList;
    }

    @Override
    public List<Map<String, Object>> statPersonalData(int days, Integer busiType) {
        List<Map<String, Object>> resultMapList = new ArrayList<>();
        // 计算需要统计的日期列表
        List<LocalDateTime> dateList = this.computeStatDateList(days);
        for (LocalDateTime statDate : dateList) {
            LocalDateTime startTime = LocalDateTime.of(statDate.toLocalDate(), LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(statDate.toLocalDate(), LocalTime.MAX);
            List<Map<String, Object>> personalMapList = personalMapper.statPersonalData(startTime, endTime, busiType);
            if (personalMapList != null && !personalMapList.isEmpty()) {
                resultMapList.addAll(personalMapList);
            } else {
                Map<String, Object> tmpMap = new HashMap<>();
                tmpMap.put("Num", 0);
                tmpMap.put("StatDate", DateUtil.format(statDate, "yyyy-MM-dd"));
                resultMapList.add(tmpMap);
            }
        }
        return resultMapList;
    }

    @Override
    public List<Map<String, Object>> statSubOrderNumData(int days) {
        List<Map<String, Object>> resultMapList = new ArrayList<>();
        // 计算需要统计的日期列表
        List<LocalDateTime> dateList = this.computeStatDateList(days);
        // 订单类型列表整理
        int[] orderTypes = new int[]{1, 2};
        // 处理所有日期
        for (LocalDateTime statDate : dateList) {
            LocalDateTime startTime = LocalDateTime.of(statDate.toLocalDate(), LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(statDate.toLocalDate(), LocalTime.MAX);
            List<Map<String, Object>> subPhyOrderMapList = subPhysicalOrderMapper.statSubOrderNum(startTime, endTime);
            for (int orderType : orderTypes) {
                Map<String, Object> tmpMap = null;
                for (Map<String, Object> subPhyOrderMap : subPhyOrderMapList) {
                    int subPhyOrderType = MapUtils.getIntValue(subPhyOrderMap, "OrderType");
                    if (subPhyOrderType == orderType) {
                        tmpMap = subPhyOrderMap;
                    }
                }
                if (tmpMap == null) {
                    tmpMap = new HashMap<>();
                    tmpMap.put("OrderType", orderType);
                    tmpMap.put("Num", 0);
                    tmpMap.put("Amount", 0);
                    tmpMap.put("StatDate", DateUtil.format(statDate, "yyyy-MM-dd"));
                }
                resultMapList.add(tmpMap);
            }
        }
        return resultMapList;
    }

    @Override
    public List<Map<String, Object>> statMaterialData(int days) {
        List<Map<String, Object>> resultMapList = new ArrayList<>();
        // 计算需要统计的日期列表
        List<LocalDateTime> dateList = this.computeStatDateList(days);
        // 处理所有日期
        for (LocalDateTime statDate : dateList) {
            LocalDateTime startTime = LocalDateTime.of(statDate.toLocalDate(), LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(statDate.toLocalDate(), LocalTime.MAX);
            List<Map<String, Object>> materialMapList = businessMapper.statMaterialData(startTime, endTime);
            if (materialMapList != null && !materialMapList.isEmpty()) {
                resultMapList.addAll(materialMapList);
            } else {
                Map<String, Object> tmpMap = new HashMap<>();
                tmpMap.put("Num", 0);
                tmpMap.put("StatDate", DateUtil.format(statDate, "yyyy-MM-dd"));
                resultMapList.add(tmpMap);
            }
        }
        return resultMapList;
    }

    @Override
    public List<Map<String, Object>> getAllMarketCode() {
        return marketMapper.getAllMarketCode();
    }

    private static List<LocalDateTime> computeStatDateList(int days) {
        return DateUtil.computeBeforeDateList(days, 0);
    }
}
